#ifndef CZ80_H_INCLUDED
#define CZ80_H_INCLUDED

#include "commons.h"

////////////////////////////////////////////////////////////////////////////////////////////////////

class CZ80 {
    public:
                        CZ80                ();
        virtual         ~CZ80               ();
        uint8_t         Fetch               ();
        int             ExecuteOpcode       ( uint8_t );

        void            SetReadPtr          ( uint8_t (*value)(uint16_t) )          { mRead  = value; }
        void            SetWritePtr         ( void (*value)(uint16_t, uint8_t) )    { mWrite = value; }

    private:
        void            StackPush           ( uint8_t );
        uint8_t         StackPop            ();
        void            ClearFlags          ( uint8_t );
        void            SetFlags            ( uint8_t );
        bool            TestFlag            ( uint8_t );
        int             ExecuteCBOpcode     ( uint8_t );

        PAIR_REGISTER   mAF;
        PAIR_REGISTER   mBC;
        PAIR_REGISTER   mDE;
        PAIR_REGISTER   mHL;
        uint16_t        mSP;
        uint16_t        mPC;
        int             mTicks;
        uint8_t         ( *mRead )          ( uint16_t );
        void            ( *mWrite )         ( uint16_t, uint8_t );

        void            ADD_8BIT            ( uint8_t );
        void            ADD_16BIT           ( uint16_t );
        void            AND_8BIT            ( uint8_t );
        void            CALL                ();
        void            COMPARE_8BIT        ( uint8_t );
        uint8_t         DECREMENT_REG_8BIT  ( uint8_t );
        void            LD_nn_SP            ();
        void            LDHL                ();
        void            LOAD_REG_8BIT       ( uint8_t&, uint8_t );
        void            LOAD_REG_16BIT      ( uint16_t& );
        uint8_t         INCREMENT_REG_8BIT  ( uint8_t );
        void            JUMP_CONDITIONAL    ( bool );
        void            JUMP_IMMEDIATE      ();
        void            OR_8BIT             ( uint8_t );
        uint8_t         RESET_BIT           ( uint8_t, int );
        void            RETURN_CONDITIONAL  ( bool );
        void            RRCA                ();
        uint8_t         SWAP_NIBBLES        ( uint8_t );
        void            TEST_BIT            ( uint8_t, int );
        void            XOR_8BIT            ( uint8_t );
};

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif